package com.heima.homeservicemanagementsystem.service.impl;

import ch.qos.logback.core.util.StringUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.heima.homeservicemanagementsystem.entity.SysPermission;
import com.heima.homeservicemanagementsystem.entity.SysRole;
import com.heima.homeservicemanagementsystem.entity.SysUserRole;
import com.heima.homeservicemanagementsystem.entity.dto.Option;
import com.heima.homeservicemanagementsystem.entity.dto.RegisterDto;
import com.heima.homeservicemanagementsystem.entity.dto.UpdataPwdDto;
import com.heima.homeservicemanagementsystem.mapper.SysUserMapper;
import com.heima.homeservicemanagementsystem.entity.SysUser;
import com.heima.homeservicemanagementsystem.mapper.SysUserRoleMapper;
import com.heima.homeservicemanagementsystem.module.Result;
import com.heima.homeservicemanagementsystem.service.SysUserRoleService;
import com.heima.homeservicemanagementsystem.service.SysUserService;
import com.heima.homeservicemanagementsystem.utils.PasswordUtils;
import com.heima.homeservicemanagementsystem.utils.RedisClient;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;

/**
 * 用户表(SysUser)表服务实现类
 *
 * @author makejava
 * @since 2025-02-26 22:55:17
 */
@Slf4j
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Autowired
    private SysUserMapper usermapper;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private SysUserRoleMapper userRoleMapper;


    @Override
    public List<Option> getRoles(String id) {
        return baseMapper.getRolesByUserId(id);
    }

    @Override
    public void insertRoles(String id, List<Object> rolesIds) {
        baseMapper.insertRolesIds(id, rolesIds);
    }

    @Override
    public void deleteRoles(String id) {
        baseMapper.deleteByUserId(id);
    }

    @Override
    public List<String> listRoleByUserId(String userId) {
        return baseMapper.getRoleCodeById(userId);

    }

    @Override
    public List<String> listPermssionByRoleCode(String roleCode) {
        return baseMapper.listPermssionByRoleCode(roleCode);
    }

    @Override
    public List<JSONObject> listmenu() {


//        List<JSONObject> data = new ArrayList<>();
//        //获取父级菜单
//        List<SysPermission> list = baseMapper.listparentMenuByuserId(StpUtil.getLoginIdAsString());
//        for (SysPermission sysPermission : list) {
//            JSONObject entries = new JSONObject();
//            entries.putOnce("path", sysPermission.getCode());
//            entries.putOnce("component", "LAYOUT");
//            JSONObject parentmeta = new JSONObject();
//            getMenuTitle(sysPermission, entries, parentmeta);
//            List<JSONObject> children = new ArrayList<>();
//            //获取子级菜单
//            List<SysPermission> childrenList = baseMapper.listMenuByuserId(StpUtil.getLoginIdAsString(), sysPermission.getId());
//            //递归子菜单
//            for (SysPermission menuInfo : childrenList) {
//                JSONObject menu = new JSONObject();
//                menu.putOnce("path", menuInfo.getCode());
//                menu.putOnce("name", menuInfo.getPath());
//
//                JSONObject meta = new JSONObject();
//                if (menuInfo.getOuterChain() == 1) {
//                    menu.putOnce("component", "IFrame");
//                    meta.putOnce("frameSrc", menuInfo.getCode());
//                } else {
//                    menu.putOnce("component", menuInfo.getCode());
//                }
//                getMenuTitle(menuInfo, menu, meta);
//                children.add(menu);
//            }
//            entries.putOnce("children", children);
//            data.add(entries);
//        }

//        return data;

        List<JSONObject> data = new ArrayList<>();
//        通过userid找到角色人然后根据角色的id将权限表的父级的菜单查询出来
        List<SysPermission> list = baseMapper.listparentMenuByuserId(StpUtil.getLoginIdAsString());
        for (SysPermission sysPermission : list) {
            JSONObject entries = new JSONObject();
            entries.putOnce("name", sysPermission.getCode());
            entries.putOnce("parentId", 0);
            entries.putOnce("id", sysPermission.getId());
            JSONObject meta = new JSONObject();
            meta.putOnce("title", sysPermission.getName());
            meta.putOnce("icon", sysPermission.getIcon());
            entries.putOnce("meta", meta);
            entries.putOnce("component", sysPermission.getPath());
            if (sysPermission.getCode().equals("dashboard")) {
                entries.putOnce("redirect", "/dashboard/workplace");//redirect: '/dashboard/workplace'
            }

            data.add(entries);
            List<SysPermission> childrenList = baseMapper.listMenuByuserId(StpUtil.getLoginIdAsString(), sysPermission.getId());
            for (SysPermission permission : childrenList) {
                JSONObject children = new JSONObject();
                children.putOnce("name", permission.getCode());
                children.putOnce("parentId", sysPermission.getId());
                children.putOnce("id", permission.getId());
                JSONObject meta1 = new JSONObject();
                meta1.putOnce("title", permission.getName());
                meta1.putOnce("icon", permission.getIcon());
                children.putOnce("meta", meta1);
                children.putOnce("component", permission.getPath());
                data.add(children);
            }
        }


        return data;
    }

    /**
     * 用户注册
     *
     * @param registerDto
     * @return com.heima.homeservicemanagementsystem.module.Result
     * @author jinchengfei
     * @create 2025/3/16
     **/

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result register(RegisterDto registerDto) {

        log.info("前端的数据：{}", registerDto);

        // 验证码校验
        if (!isCaptchaValid(registerDto)) {
            return Result.error("验证码不正确");
        }

        // 用户名、手机号、邮箱唯一性检查
        if (isUserExists(registerDto)) {
            return Result.error("用户已经注册过啦，请先去登录");
        }
        // 填充 SysUser 对象并处理密码
        SysUser sysUser = createSysUserFromDto(registerDto);

        // 插入数据库
        int insertResult = usermapper.insert(sysUser);
        if (insertResult > 0) {
            return getResult(sysUser);

        } else {
            return Result.error("注册失败，已注册该用户");
        }

    }

    @Override
    public Result updataPwd(UpdataPwdDto updataPwdDto) {

        log.info("前端的数据：{}", updataPwdDto);
        log.info("duibi:{}", isCodeValid(updataPwdDto));
        if (!isCodeValid(updataPwdDto)) {
            return Result.error("验证码不正确");
        }
        String email1 = updataPwdDto.getEmail();
        SysUser email = usermapper.selectOne(new QueryWrapper<SysUser>().eq("email", email1));

        if (Objects.nonNull(email)) {
            LambdaUpdateWrapper<SysUser> lambdaUpdateWrapper = new UpdateWrapper<SysUser>().lambda();
            SysUser sysUser = new SysUser();
            String salt = RandomUtil.randomString(16);
            sysUser.setSlat(salt);
            String encryptedPassword = PasswordUtils.encrypt(salt, updataPwdDto.getPassword());
            sysUser.setPassword(encryptedPassword);

            lambdaUpdateWrapper.set(sysUser.getPassword() != null, SysUser::getPassword, sysUser.getPassword())
                    .set(sysUser.getSlat() != null, SysUser::getSlat, sysUser.getSlat())
                    .eq(SysUser::getEmail, email1);
            if (usermapper.update(null, lambdaUpdateWrapper) > 0) {
                return Result.success("修改成功");
            }
            return Result.error("修改失败");

        }
        return Result.error("用户未进行绑定或者用户未进行注册");

    }

    //自己写的获取用户逇角色
    @Override
    public List<JSONObject> getuserRoles() {
        log.info("用户的id；{}", StpUtil.getLoginIdAsString());
        List<SysRole> sysRoles = baseMapper.getuserRoles(StpUtil.getLoginIdAsString());
        log.info("用户角色:{}", sysRoles);
        List<JSONObject> data = new ArrayList<>();
        for (SysRole sysRole : sysRoles) {
            JSONObject entries = new JSONObject();
            entries.putOnce("id", sysRole.getId());
            entries.putOnce("name", sysRole.getCode());
            entries.putOnce("describe", sysRole.getName());
            entries.putOnce("status", sysRole.getStatus());
//            ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTimeString, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(sysRole.getCreateTime());
            long timeInMillis = calendar.getTimeInMillis();
            // 转换为时间戳（毫秒）
//            long timestamp = zonedDateTime.toInstant().toEpochMilli();
            entries.putOnce("createTime", timeInMillis);
            List<SysPermission> permissions = baseMapper.ressyspressionByid(sysRole.getId());
            log.info("当前用户逇权限信息：{}，{}", permissions, sysRole.getId());
            entries.putOnce("permissions", permissions);
            data.add(entries);
        }
        log.info("huode :{}", data);

        return data;

    }


    private boolean isCodeValid(UpdataPwdDto updataPwdDto) {
        String redisCaptcha = redisClient.get("emailCode-" + updataPwdDto.getEmail());
        log.info("验证码:{}, 数据:{}", updataPwdDto.getCode(), redisCaptcha);
        return redisCaptcha.equals(updataPwdDto.getCode());
    }


    private Result<?> getResult(SysUser sysUser) {//事务进行回滚就是假如插入失败的话就抛出异常将插入的信息进行回滚
        List<SysUserRole> sysUserRoles = userRoleMapper.selectList(new QueryWrapper<SysUserRole>().eq("user_id", sysUser.getId()).eq("role_id", "1895452596287164418"));
        boolean empty = CollectionUtils.isEmpty(sysUserRoles);
//        log.info("是否为空:{}", empty);
        if (empty) {
            ArrayList<Object> roid = new ArrayList<>();
            roid.add("1895452596287164418");
            insertRole(sysUser.getId(), roid);
            return Result.success("注册成功");
        } else {
            return Result.error("用户已拥有该角色，无需再次分配");
        }
    }

    private void insertRole(String userId, ArrayList<Object> roles) {
        // 插入角色信息
        for (Object role : roles) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(role.toString());

            int insertRoleResult = userRoleMapper.insert(sysUserRole);
            if (insertRoleResult <= 0) {
                // 如果插入失败，抛出异常，Spring 会自动回滚事务
//                触发回滚前面的事务，回滚事务
                throw new RuntimeException("角色注册失败，用户已存在");

            }
        }
    }

    // 校验验证码
    private boolean isCaptchaValid(RegisterDto registerDto) {
        String redisCaptcha = redisClient.get("mobileCode-" + registerDto.getPhone());
        log.info("验证码:{}, 数据:{}", registerDto.getCaptcha(), redisCaptcha);
        return registerDto.getCaptcha().equals(redisCaptcha);
    }

    // 检查用户是否已经存在
    private boolean isUserExists(RegisterDto registerDto) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(registerDto.getUsername() != null, SysUser::getUsername, registerDto.getUsername()).or()
                .eq(registerDto.getPhone() != null, SysUser::getPhone, registerDto.getPhone()).or()
                .eq(registerDto.getEmail() != null, SysUser::getEmail, registerDto.getEmail());
        List<SysUser> sysUsers = usermapper.selectList(wrapper);

//        return sysUsers != null;
        return !CollectionUtils.isEmpty(sysUsers);
    }

    // 创建 SysUser 并加密密码
    private SysUser createSysUserFromDto(RegisterDto registerDto) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(registerDto, sysUser);

        // 生成盐并加密密码
        String salt = RandomUtil.randomString(16);
        sysUser.setSlat(salt);
        String encryptedPassword = PasswordUtils.encrypt(salt, registerDto.getPassword());
        sysUser.setPassword(encryptedPassword);

        return sysUser;
    }

//    private void getMenuTitle(SysPermission menuInfo, JSONObject menu, JSONObject meta) {
//        JSONObject title = new JSONObject();
//        title.putOnce("zh_CN", menuInfo.getName());
//        title.putOnce("en_US", menuInfo.getEnglishName());
//        meta.putOnce("title", title);
//        meta.putOnce("icon", menuInfo.getIcon());
//        menu.putOnce("meta", meta);
//    }
}

